package com.qiaofang.collectmanage.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.qiaofang.collectmanage.cache.constants.CollectManageRedisKeyConstants;
import com.qiaofang.collectmanage.cache.redis.CollectManageRedis;
import com.qiaofang.collectmanage.dao.CollectRuleDao;
import com.qiaofang.collectmanage.dao.CrawlerSubTaskDao;
import com.qiaofang.collectmanage.dao.CrawlerTaskDao;
import com.qiaofang.collectmanage.dao.domain.CrawlerSubTask;
import com.qiaofang.collectmanage.dao.domain.CrawlerTask;
import com.qiaofang.collectmanage.domain.CollectRule;
import com.qiaofang.collectmanage.stub.bean.*;
import com.qiaofang.collectmanage.stub.constants.DeletedEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.qiaofang.common.model.page.PageDTO;
import com.qiaofang.collectmanage.service.CrawlerTaskService;
import com.qiaofang.collectmanage.dao.CrawlerTaskDao;
import com.qiaofang.collectmanage.dao.domain.CrawlerTask;
import com.qiaofang.collectmanage.service.util.CrawlerTaskConvert;

/**
* Created by generator on 2018-8-1 13:49:21
*/
@Service("taskService")
public class CrawlerTaskServiceImpl implements CrawlerTaskService {

    Logger logger = LoggerFactory.getLogger(CrawlerTaskServiceImpl.class);

    @Autowired
    private CrawlerTaskDao taskDao;

    @Autowired
    private CrawlerSubTaskDao crawlerSubTaskDao;

    @Autowired
    private CollectRuleDao collectRuleDao;

    @Autowired
    CollectManageRedis collectManageRedis;

    private Map taskCache = new HashMap();

    @Override
    public CrawlerTaskDTO getCrawlerTaskByUuid(String uuid){
        CrawlerTask domain = taskDao.getCrawlerTaskByUuid(uuid);
        return   CrawlerTaskConvert.convertDomain2DTO(domain);
    }
    @Override
    public CrawlerTaskDTO getCrawlerTaskByTask(CrawlerTaskDTO dto){
        CrawlerTask domain = taskDao.getCrawlerTaskByCrawlerTask(CrawlerTaskConvert.convertDTO2Domain(dto));
          return CrawlerTaskConvert.convertDomain2DTO(domain);
    }

    @Override
    public int saveCrawlerTask(SaveCrawlerTaskDTO dto) {
         return taskDao.saveCrawlerTask (CrawlerTaskConvert.convertSaveDTO2Domain(dto));
    }

    @Override
    public int updateCrawlerTask (UpdateCrawlerTaskDTO dto) {
         return taskDao.updateCrawlerTask( CrawlerTaskConvert.convertUpdateDTO2Domain(dto));
    }


    @Override
    public int removeCrawlerTaskByUuid (String uuid) {
      return taskDao.removeCrawlerTaskByUuid(uuid);
    }
    @Override
    public List<CrawlerTaskDTO> listCrawlerTask(ListCrawlerTaskDTO dto){
          return  taskDao.listCrawlerTask(CrawlerTaskConvert.convertListDTO2Domain(dto)).stream().map(CrawlerTaskConvert::convertDomain2DTO).collect(Collectors.toList());
    }


    @Override
    public List<CrawlerTaskDTO> listCrawlerTaskByUuids(List<String> uuidList){
         return  taskDao.listCrawlerTaskByUuids(uuidList).stream().map(CrawlerTaskConvert::convertDomain2DTO).collect(Collectors.toList());
    }
    @Override
    public Long countCrawlerTask(CrawlerTaskDTO dto){
        return  taskDao.countCrawlerTask(CrawlerTaskConvert.convertDTO2Domain(dto));
    }
    @Override
    public List<CrawlerTaskDTO> searchCrawlerTaskByPermission(SearchCrawlerTaskDTO dto, PageDTO page){
        List<CrawlerTask> list = taskDao.searchCrawlerTaskByPermission(dto,page);
        return list!=null?list.stream().map(CrawlerTaskConvert::convertDomain2DTO).collect(Collectors.toList()):null;
    }
    @Override
    public Long countCrawlerTaskByPermission(SearchCrawlerTaskDTO dto){
           return taskDao.countCrawlerTaskByPermission(dto);
    }

    /**
     * 清空CollectManageRedisKeyConstants.crawlerCollectRuleDTO
     * 的redis缓存爬虫频道及缓存任务
     */
    @Override
    public void clearCrawlerCollectCache(List<Integer> ids){
        Long start = System.currentTimeMillis();
        //通过ids获取所有爬虫任务
        List<CrawlerTask> crawlerTasks = taskDao.listCrawlerTaskByIds(ids);
        if(crawlerTasks!=null) {
            for (CrawlerTask crawlerTask : crawlerTasks) {
                //获取所有爬虫子任务
                CrawlerSubTask crawlerSubTaskReq = new CrawlerSubTask();
                crawlerSubTaskReq.setCrawlerTaskUuid(crawlerTask.getUuid());
                crawlerSubTaskReq.setDeleted(DeletedEnum.NO.getValue());
                List<CrawlerSubTask> crawlerSubTasks = crawlerSubTaskDao.listCrawlerSubTask(crawlerSubTaskReq);
                if (crawlerSubTasks != null && !crawlerSubTasks.isEmpty()) {
                    //获取所有规则唯一标识collectRuleUuid
                    List<String> collectRuleUuids = crawlerSubTasks.stream().map(CrawlerSubTask::getCollectRuleUuid).collect(Collectors.toList());
                    if (collectRuleUuids != null && !collectRuleUuids.isEmpty()) {
                        //获取所有采集规则,去掉重复的采集规则
                        collectRuleUuids = collectRuleUuids.stream().distinct().collect(Collectors.toList());
                        List<com.qiaofang.collectmanage.dao.domain.CollectRule> collectRules = collectRuleDao.listCollectRuleByUuids(collectRuleUuids);
                        if (collectRules != null && !collectRules.isEmpty()) {
                            for (com.qiaofang.collectmanage.dao.domain.CollectRule collectRule : collectRules) {
                                if (collectManageRedis.hashHasKey(CollectManageRedisKeyConstants.CRAWLER_COLLECTRULE, collectRule.getUuid())) {
                                    collectManageRedis.deleteKey(collectRule.getUuid());
                                }
                            }
                        }
                    }
                }
                taskCache.put(crawlerTask.getId(),null);
            }
        }
        logger.info("清空采集缓存任务耗时{}ms",System.currentTimeMillis()-start);
    }

    /**
     * 通过任务ids获取爬虫CrawlerCollectRuleDTO
     * @param ids
     * @return
     */
    @Override
    public List<CrawlerTaskRelatedDTO> listCrawlerCollectRuleByIds(List<Integer> ids) {
        Long start = System.currentTimeMillis();
        List<CrawlerTaskRelatedDTO> crawlerTaskRelatedDTOs = new ArrayList<>();

        //通过ids获取所有爬虫任务
        List<CrawlerTask> crawlerTasks = taskDao.listCrawlerTaskByIds(ids);
        if(crawlerTasks!=null){
            for(CrawlerTask crawlerTask :crawlerTasks){

                if(taskCache.get(crawlerTask.getId())==null){
                    List<CrawlerCollectRuleDTO>  crawlerCollectRuleDTOs = new ArrayList<CrawlerCollectRuleDTO>();
                    //获取所有爬虫子任务
                    CrawlerSubTask crawlerSubTaskReq = new CrawlerSubTask();
                    crawlerSubTaskReq.setCrawlerTaskUuid(crawlerTask.getUuid());
                    crawlerSubTaskReq.setDeleted(DeletedEnum.NO.getValue());
                    Long stratSubTask = System.currentTimeMillis();
                    List<CrawlerSubTask> crawlerSubTasks = crawlerSubTaskDao.listCrawlerSubTask(crawlerSubTaskReq);
                    logger.info("获取子任务crawlerSubTasks耗时{}ms",System.currentTimeMillis()-stratSubTask);
                    if(crawlerSubTasks!=null&&!crawlerSubTasks.isEmpty()){
                        //获取所有规则唯一标识collectRuleUuid
                        List<String> collectRuleUuids  =crawlerSubTasks.stream().map(CrawlerSubTask::getCollectRuleUuid).collect(Collectors.toList());
                        if(collectRuleUuids!=null&&!collectRuleUuids.isEmpty()){
                            //获取所有采集规则,去掉重复的采集规则
                            collectRuleUuids = collectRuleUuids.stream().distinct().collect(Collectors.toList());
                            List<com.qiaofang.collectmanage.dao.domain.CollectRule> collectRules = collectRuleDao.listCollectRuleByUuids(collectRuleUuids);
                            if(collectRules!=null&&!collectRules.isEmpty()){
                                Long startChanne = System.currentTimeMillis();
                                for(com.qiaofang.collectmanage.dao.domain.CollectRule collectRule : collectRules) {
                                    if(!collectManageRedis.hashHasKey(CollectManageRedisKeyConstants.CRAWLER_COLLECTRULE,collectRule.getUuid()))
                                    {
                                        Long collectRuleTime = System.currentTimeMillis();
                                        CrawlerCollectRuleDTO crawlerCollectRuleDTO =  collectRuleDao.findCrawlerCollectRuleById(collectRule);
                                        logger.info("装载单个频道耗时{}ms",System.currentTimeMillis()-collectRuleTime);
                                        collectManageRedis.putHash(CollectManageRedisKeyConstants.CRAWLER_COLLECTRULE,collectRule.getUuid(),crawlerCollectRuleDTO);
                                    }
                                    CrawlerCollectRuleDTO crawlerCollectRuleDTO = (CrawlerCollectRuleDTO) collectManageRedis.getRedisTemplate().opsForHash().get(CollectManageRedisKeyConstants.CRAWLER_COLLECTRULE,collectRule.getUuid());
                                    crawlerCollectRuleDTOs.add(crawlerCollectRuleDTO);
                                }
                                logger.info("装载单个任务所有频道耗时{}ms",System.currentTimeMillis()-startChanne);
                            }
                        }
                    }
                    CrawlerTaskRelatedDTO crawlerTaskRelatedDTO = new CrawlerTaskRelatedDTO();
                    crawlerTaskRelatedDTO.setCrawlerTaskDTO(CrawlerTaskConvert.convertDomain2DTO(crawlerTask));
                    crawlerTaskRelatedDTO.setCrawlerCollectRuleDTOs(crawlerCollectRuleDTOs);
                    taskCache.put(crawlerTask.getId(),crawlerTaskRelatedDTO);
                }
                CrawlerTaskRelatedDTO  crawlerTaskRelatedDTO = (CrawlerTaskRelatedDTO)taskCache.get(crawlerTask.getId());
                crawlerTaskRelatedDTOs.add(crawlerTaskRelatedDTO);
            }
        }
        logger.info("获取采集任务耗时{}ms",System.currentTimeMillis()-start);
        return crawlerTaskRelatedDTOs;
    }
}
